package com.hzw.saas.web.admin.security;

import com.hzw.saas.api.rbac.IUserRoleService;
import com.hzw.saas.api.rbac.bo.RoleBO;
import com.hzw.saas.api.rbac.enums.PermSysEnum;
import com.hzw.saas.api.sys.dto.SysUserAccountDto;
import com.hzw.saas.api.sys.service.ISysUserService;
import com.hzw.saas.api.user.IStaffService;
import com.hzw.saas.api.user.bo.StaffBO;
import com.hzw.saas.common.security.pojo.dto.SaasUser;
import lombok.RequiredArgsConstructor;
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@RequiredArgsConstructor
public class AdminAdditionalInformation implements TokenEnhancer {

    private final IUserRoleService userRoleService;
    private final IStaffService staffService;
    private final ISysUserService sysUserService;

    @Override
    public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
        Map<String, Object> info = accessToken.getAdditionalInformation();
        Object principal = authentication.getPrincipal();
        if(principal instanceof SaasUser) {
            String userId = ((SaasUser) principal).getUserId();
            SysUserAccountDto sysUser = sysUserService.get(userId);
            info.put("authorities", getUserPermissions(userId));
            info.put("roles", getRoles(userId));
            info.put("realName", getRealName(sysUser.getUserName(), sysUser.getPhoneNo(), sysUser.getEmail()));
            info.put("userId", userId);
            ((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(info);
        }
        return accessToken;
    }

    private String[] getUserPermissions(String userId) {
        List<String> authorities = userRoleService.listAuthorities(PermSysEnum.ADMIN.getCode(), userId);
        return authorities.toArray(new String[0]);
    }

    private List<String> getRoles(String userId) {
        List<RoleBO> roles = userRoleService.listRoles(PermSysEnum.ADMIN.getCode(), userId);
        return roles.stream().map(RoleBO::getName).collect(Collectors.toList());
    }

    private String getRealName(String username, String phoneNo, String email) {
        StaffBO staffBO = staffService.queryByPhoneNo(phoneNo);
        if (Objects.isNull(staffBO)) {
            staffBO = staffService.getByEmail(email);
        }
        return Objects.isNull(staffBO) ? username : staffBO.getStaffName();
    }

}
